home *** CD-ROM | disk | FTP | other *** search
/ Speccy ClassiX 1998 / Speccy ClassiX 98.iso / amiga_system / the_aminet / dev / gcc / ixemulsrc.lha / ixemul-41.4 / library / kern_sig.c < prev    next >
C/C++ Source or Header  |  1995-09-27  |  21KB  |  901 lines

  1. /*
  2.  *  This file is part of ixemul.library for the Amiga.
  3.  *  Copyright (C) 1991, 1992  Markus M. Wild
  4.  *  Portions Copyright (C) 1994 Rafael W. Luebbert
  5.  *
  6.  *  This library is free software; you can redistribute it and/or
  7.  *  modify it under the terms of the GNU Library General Public
  8.  *  License as published by the Free Software Foundation; either
  9.  *  version 2 of the License, or (at your option) any later version.
  10.  *
  11.  *  This library is distributed in the hope that it will be useful,
  12.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  13.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  14.  *  Library General Public License for more details.
  15.  *
  16.  *  You should have received a copy of the GNU Library General Public
  17.  *  License along with this library; if not, write to the Free
  18.  *  Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  19.  *
  20.  *  $Id: kern_sig.c,v 1.6 1994/07/11 00:32:56 rluebbert Exp $
  21.  *
  22.  *  $Log: kern_sig.c,v $
  23.  *  Revision 1.6  1994/07/11  00:32:56  rluebbert
  24.  *  Put issig back in.
  25.  *
  26.  *  Revision 1.5  1994/07/11  00:27:37  rluebbert
  27.  *  Commented out unused issig
  28.  *
  29.  *  Revision 1.4  1994/06/19  15:13:35  rluebbert
  30.  *  *** empty log message ***
  31.  *
  32.  *  Revision 1.2  1992/07/04  19:19:51  mwild
  33.  *  change to new ix_sleep() semantics
  34.  *
  35.  * Revision 1.1  1992/05/14  19:55:40  mwild
  36.  * Initial revision
  37.  *
  38.  *
  39.  *  Since the code originated from Berkeley, the following copyright
  40.  *  header applies as well. The code has been changed, it's not the
  41.  *  original Berkeley code!
  42.  */
  43.  
  44. /*
  45.  * Copyright (c) 1982, 1986, 1989 Regents of the University of California.
  46.  * All rights reserved.
  47.  *
  48.  * Redistribution is only permitted until one year after the first shipment
  49.  * of 4.4BSD by the Regents.  Otherwise, redistribution and use in source and
  50.  * binary forms are permitted provided that: (1) source distributions retain
  51.  * this entire copyright notice and comment, and (2) distributions including
  52.  * binaries display the following acknowledgement:  This product includes
  53.  * software developed by the University of California, Berkeley and its
  54.  * contributors'' in the documentation or other materials provided with the
  55.  * distribution and in all advertising materials mentioning features or use
  56.  * of this software.  Neither the name of the University nor the names of
  57.  * its contributors may be used to endorse or promote products derived from
  58.  * this software without specific prior written permission.
  59.  * THIS SOFTWARE IS PROVIDED AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
  60.  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
  61.  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  62.  *
  63.  *    @(#)kern_sig.c    7.23 (Berkeley) 6/28/90
  64.  */
  65.  
  66. #define KERNEL
  67. #include "ixemul.h"
  68. #include "kprintf.h"
  69.  
  70. extern struct ExecBase *SysBase;
  71.  
  72. #include <wait.h>
  73.  
  74. #define    ttystopsigmask    (sigmask(SIGTSTP)|sigmask(SIGTTIN)|sigmask(SIGTTOU))
  75. #define    stopsigmask    (sigmask(SIGSTOP)|ttystopsigmask)
  76. #define defaultignmask    (sigmask(SIGCONT)|sigmask(SIGIO)|sigmask(SIGURG)| \
  77.             sigmask(SIGCHLD)|sigmask(SIGWINCH)|sigmask(SIGINFO)|sigmask(SIGMSG))
  78.  
  79. #define getuser(p)    ((struct user *)((p)->pr_Task.tc_TrapData))
  80.  
  81. void setsigvec (int sig, struct sigaction *sa);
  82. void _psignal (struct Task *t, int sig);
  83. void sig_exit (int code);
  84.  
  85. /*
  86.  * Can process p send the signal signo to process q?
  87.  */
  88. #define CANSIGNAL(p, q, signo) (1)
  89.  
  90. int
  91. sigaction (int sig, const struct sigaction *nsa, struct sigaction *osa)
  92. {
  93.   struct sigaction vec;
  94.   register struct sigaction *sa;
  95.   int bit, error;
  96.  
  97.   if (sig <= 0 || sig >= NSIG || sig == SIGKILL || sig == SIGSTOP)
  98.     {
  99.       errno = EINVAL;
  100.       KPRINTF (("&errno = %lx, errno = %ld\n", &errno, errno));
  101.       return -1;
  102.     }
  103.  
  104.   sa = &vec;
  105.   if (osa)
  106.     {
  107.       sa->sa_handler = u.u_signal[sig];
  108.       sa->sa_mask = u.u_sigmask[sig];
  109.       bit = sigmask(sig);
  110.       sa->sa_flags = 0;
  111.       if ((u.u_sigonstack & bit) != 0)
  112.     sa->sa_flags |= SA_ONSTACK;
  113.  
  114.       if ((u.u_sigintr & bit) == 0)
  115.     sa->sa_flags |= SA_RESTART;
  116.  
  117.       if (u.p_flag & SNOCLDSTOP)
  118.     sa->sa_flags |= SA_NOCLDSTOP;
  119.  
  120.       *osa = *sa;
  121.     }
  122.  
  123.   if (nsa)
  124.     {
  125.       *sa = *nsa;
  126.       setsigvec(sig, sa);
  127.     }
  128.   
  129.   return (0);
  130. }
  131.  
  132. void
  133. setsigvec (int sig, struct sigaction *sa)
  134. {
  135.   register int bit;
  136.  
  137.   bit = sigmask(sig);
  138.   /*
  139.    * Change setting atomically.
  140.    */
  141.   Disable();
  142.  
  143.   u.u_signal[sig] = sa->sa_handler;
  144.   u.u_sigmask[sig] = sa->sa_mask &~ sigcantmask;
  145.  
  146.   if ((sa->sa_flags & SA_RESTART) == 0)
  147.     u.u_sigintr |= bit;
  148.   else
  149.     u.u_sigintr &= ~bit;
  150.  
  151.   if (sa->sa_flags & SA_ONSTACK)
  152.     u.u_sigonstack |= bit;
  153.   else
  154.     u.u_sigonstack &= ~bit;
  155.  
  156.   if (sig == SIGCHLD) 
  157.     {
  158.       if (sa->sa_flags & SA_NOCLDSTOP)
  159.     u.p_flag |= SNOCLDSTOP;
  160.       else
  161.     u.p_flag &= ~SNOCLDSTOP;
  162.     }
  163.  
  164.   /*
  165.    * Set bit in p_sigignore for signals that are set to SIG_IGN,
  166.    * and for signals set to SIG_DFL where the default is to ignore.
  167.    * However, don't put SIGCONT in p_sigignore,
  168.    * as we have to restart the process.
  169.    */
  170.   if (sa->sa_handler == SIG_IGN ||
  171.       (bit & defaultignmask && sa->sa_handler == SIG_DFL)) 
  172.     {
  173.       u.p_sig &= ~bit;        /* never to be seen again */
  174.       if (sig != SIGCONT)
  175.     u.p_sigignore |= bit;    /* easier in _psignal */
  176.       u.p_sigcatch &= ~bit;
  177.     }
  178.   else 
  179.     {
  180.       u.p_sigignore &= ~bit;
  181.       if (sa->sa_handler == SIG_DFL)
  182.     u.p_sigcatch &= ~bit;
  183.       else
  184.     u.p_sigcatch |= bit;
  185.     }
  186.  
  187.   Enable();
  188. }
  189.  
  190.  
  191. /*
  192.  * Manipulate signal mask.
  193.  */
  194.  
  195. int
  196. sigprocmask (int how, const sigset_t *mask, sigset_t *omask)
  197. {
  198.   if (omask)
  199.     *omask = u.p_sigmask;
  200.  
  201.   if (mask)
  202.     {
  203.       Disable();
  204.  
  205.       switch (how) 
  206.         {
  207.         case SIG_BLOCK:
  208.       u.p_sigmask |= *mask &~ sigcantmask;
  209.       break;
  210.  
  211.         case SIG_UNBLOCK:
  212.       u.p_sigmask &= ~*mask;
  213.       break;
  214.  
  215.         case SIG_SETMASK:
  216.       u.p_sigmask = *mask &~ sigcantmask;
  217.       break;
  218.     
  219.         default:
  220.       errno = EINVAL;
  221.       KPRINTF (("&errno = %lx, errno = %ld\n", &errno, errno));
  222.       goto err_ret;
  223.         }
  224.  
  225.       Enable();
  226.     }
  227.  
  228.   if (CURSIG (&u))
  229.     setrun (FindTask (0));
  230.  
  231.   return 0;
  232.  
  233. err_ret:
  234.   Enable ();
  235.   return -1;
  236. }
  237.  
  238. int
  239. sigpending (sigset_t *sigs)
  240. {
  241.   *sigs = u.p_sig;
  242.   return 0;
  243. }
  244.  
  245. /*
  246.  * Generalized interface signal handler, 4.3-compatible.
  247.  * (included in amiga version, because I want to reduce the static part of the
  248.  *  library to a minimum)
  249.  */
  250. /* ARGSUSED */
  251. int
  252. sigvec(int sig, const struct sigvec *nsv, struct sigvec *osv)
  253. {
  254.   struct sigvec vec;
  255.   register struct sigvec *sv;
  256.   struct user *p = &u;
  257.   int bit, error;
  258.  
  259.   if (sig <= 0 || sig >= NSIG || sig == SIGKILL || sig == SIGSTOP)
  260.     {
  261.       *p->u_errno = EINVAL;
  262.       KPRINTF (("&errno = %lx, errno = %ld\n", &errno, errno));
  263.       return -1;
  264.     }
  265.  
  266.   sv = &vec;
  267.   if (osv) 
  268.     {
  269.       *(sig_t *)&sv->sv_handler = p->u_signal[sig];
  270.       sv->sv_mask = p->u_sigmask[sig];
  271.       bit = sigmask(sig);
  272.       sv->sv_flags = 0;
  273.       if ((p->u_sigonstack & bit) != 0)
  274.     sv->sv_flags |= SV_ONSTACK;
  275.       if ((p->u_sigintr & bit) != 0)
  276.     sv->sv_flags |= SV_INTERRUPT;
  277.       if (p->p_flag & SNOCLDSTOP)
  278.     sv->sv_flags |= SA_NOCLDSTOP;
  279.       *osv = *sv;
  280.     }
  281.  
  282.   if (nsv) 
  283.     {
  284.       *sv = *nsv;
  285.       sv->sv_flags ^= SA_RESTART;    /* opposite of SV_INTERRUPT */
  286.       setsigvec(sig, (struct sigaction *)sv);
  287.     }
  288.  
  289.   return (0);
  290. }
  291.  
  292. sigset_t
  293. sigblock (sigset_t mask)
  294. {
  295.   sigset_t result;
  296.  
  297.   Disable();
  298.   result = u.p_sigmask;
  299.   u.p_sigmask |= mask &~ sigcantmask;
  300.   (void) Enable();
  301.  
  302.   errno = 0;
  303.   KPRINTF (("&errno = %lx, errno = %ld\n", &errno, errno));
  304.   return result;
  305. }
  306.  
  307. sigset_t
  308. sigsetmask(sigset_t mask)
  309. {
  310.   sigset_t result;
  311.   struct user *p = &u;
  312.  
  313.   Disable();
  314.   result = u.p_sigmask;
  315.   u.p_sigmask = mask &~ sigcantmask;
  316.   Enable();
  317.  
  318.   if (CURSIG (p))
  319.     setrun (FindTask (0));
  320.  
  321.   errno = 0;
  322.   KPRINTF (("&errno = %lx, errno = %ld\n", &errno, errno));
  323.   return result;
  324. }
  325.  
  326. /*
  327.  * Suspend process until signal, providing mask to be set
  328.  * in the meantime. 
  329.  */
  330. /* ARGSUSED */
  331. int
  332. sigsuspend (const sigset_t *mask)
  333. {
  334.   struct user *p = &u;
  335.   int rc;
  336.  
  337.  
  338.   /*
  339.    * When returning from sigpause, we want
  340.    * the old mask to be restored after the
  341.    * signal handler has finished.  Thus, we
  342.    * save it here and mark the proc structure
  343.    * to indicate this (should be in u.).
  344.    */
  345.  
  346.   Disable ();
  347.   p->u_oldmask = p->p_sigmask;
  348.   p->p_flag |= SOMASK;
  349.   p->p_sigmask = *mask &~ sigcantmask;
  350.  
  351.  
  352.   /* NOTE: we have to specify SIGBREAKF_CTRL_C here, as the OS doesn't seem
  353.    *       to reschedule our task, if it receives a signal it isn't waiting
  354.    *       for. If SIGINT is ignored, then this will jump back into the Wait,
  355.    *       if not, we're leaving correctly, since we waited for a signal
  356.    *       that now occured (lucky we, the OS tests the Recvd-field before
  357.    *       tc_Launch has a chance to reset it ;-))
  358.    */
  359.  
  360.   while (ix_sleep (p, "sigsuspend") == 0);
  361.   Enable ();
  362.  
  363.   setrun (FindTask (0));
  364.  
  365.   p->p_sigmask = p->u_oldmask;
  366.  
  367.   if (CURSIG (p))
  368.     setrun (FindTask (0));
  369.  
  370.   /* always return EINTR rather than ERESTART... */
  371.   errno = EINTR;
  372.   KPRINTF (("&errno = %lx, errno = %ld\n", &errno, errno));
  373.   return -1;
  374. }
  375.  
  376.  
  377. int
  378. sigpause (sigset_t mask)
  379. {
  380.   return sigsuspend (&mask);
  381. }
  382.  
  383.  
  384. /* ARGSUSED */
  385. int
  386. sigstack(const struct sigstack *nss, struct sigstack *oss)
  387. {
  388.   if (oss) *oss = u.u_sigstack;
  389.   if (nss) u.u_sigstack = *nss;
  390.  
  391.   return 0;
  392. }
  393.  
  394.  
  395. /*
  396.  * Initialize signal state for process 0;
  397.  * set to ignore signals that are ignored by default.
  398.  */
  399. void
  400. siginit(struct user *p)
  401. {
  402.   p->p_sigignore = defaultignmask &~ sigmask(SIGCONT);
  403. }
  404.  
  405. /*
  406.  * This looks for the process p, validates it, and checks, whether the process
  407.  * is currently using our signal mechanism (checks magic cookie in struct user)
  408.  */
  409. static inline struct Task *
  410. pfind (pid_t p)
  411. {
  412.   struct Task *t;
  413.   
  414.   if (p && !(p & 1))
  415.     {
  416.       t = (struct Task *) p;
  417.       if (t->tc_Node.ln_Type == NT_TASK ||
  418.           t->tc_Node.ln_Type == NT_PROCESS)
  419.         {
  420.           struct user *tu = (struct user *) t->tc_TrapData;
  421.           if (tu && !((int)t->tc_TrapData & 1) && tu->u_ixbase == u.u_ixbase)
  422.         return t;
  423.     }
  424.     }
  425.   else if (! p)
  426.     return FindTask (0);
  427.  
  428.   return 0;
  429. }
  430.  
  431. /* ARGSUSED */
  432. int
  433. kill(pid_t pid, int signo)
  434. {
  435.   register struct Task *t;
  436.  
  437.   if ((unsigned) signo >= NSIG)
  438.     {
  439.       errno = EINVAL;
  440.       KPRINTF (("&errno = %lx, errno = %ld\n", &errno, errno));
  441.       return -1;
  442.     }
  443.  
  444.   if (pid >= 0)
  445.     {
  446.       /* kill single process */
  447.       t = pfind(pid);
  448.       if (t == 0)
  449.         {
  450.       /* there is a small chance, if pid == 0, that we may send the signal
  451.        * as well. If signo == SIGINT, and pid refers to a valid Task, we send
  452.        * it a SIGBREAKF_CTRL_C */
  453.       if ((signo == SIGINT) && pid && !(pid & 1))
  454.         {
  455.           t = (struct Task *) pid;
  456.           if (t->tc_Node.ln_Type == NT_TASK ||
  457.               t->tc_Node.ln_Type == NT_PROCESS)
  458.             {
  459.           Signal (t, SIGBREAKF_CTRL_C);
  460.           return 0;
  461.         }
  462.         }
  463.  
  464.           errno = ESRCH;
  465.       KPRINTF (("&errno = %lx, errno = %ld\n", &errno, errno));
  466.           return -1;
  467.         }
  468.     
  469.       if (signo)
  470.     _psignal(t, signo);
  471.     
  472.       return (0);
  473.     }
  474.  
  475.   /* signalling process groups is not (yet) implemented */  
  476.   errno = ESRCH;
  477.   KPRINTF (("&errno = %lx, errno = %ld\n", &errno, errno));
  478.   return -1;
  479. }
  480.  
  481. /* ARGSUSED */
  482. int
  483. killpg(int pgid, int signo)
  484. {
  485.   if ((unsigned) signo >= NSIG)
  486.     errno = EINVAL;
  487.   else
  488.     errno = ESRCH;
  489.   KPRINTF (("&errno = %lx, errno = %ld\n", &errno, errno));
  490.  
  491.   /* signalling process groups is not (yet) implemented */  
  492.   return -1;
  493. }
  494.  
  495. /*
  496.  * Send a signal caused by a trap to the current process.
  497.  * If it will be caught immediately, deliver it with correct code.
  498.  * Otherwise, post it normally.
  499.  */
  500. int
  501. trapsignal(struct Task *t, int sig, unsigned code, void *addr)
  502. {
  503.   int mask;
  504.  
  505.   mask = sigmask(sig);
  506.   if ((u.p_flag & STRC) == 0 && (u.p_sigcatch & mask) != 0 &&
  507.       (u.p_sigmask & mask) == 0)
  508.     {
  509.       u.u_ru.ru_nsignals++;
  510.       sendsig(t->tc_TrapData, u.u_signal[sig], sig, u.p_sigmask, code, addr);
  511.       u.p_sigmask |= u.u_sigmask[sig] | mask;
  512.       setrun (t);
  513.     }
  514.   else
  515.     {
  516.       u.u_code = code;    /* XXX for core dump/debugger */
  517.       _psignal(t, sig);
  518.     }
  519. }
  520.  
  521. /*
  522.  * Send the specified signal to the specified process.
  523.  * Most signals do not do anything directly to a process;
  524.  * they set a flag that asks the process to do something to itself.
  525.  * Exceptions:
  526.  *   o When a stop signal is sent to a sleeping process that takes the default
  527.  *     action, the process is stopped without awakening it.
  528.  *   o SIGCONT restarts stopped processes (or puts them back to sleep)
  529.  *     regardless of the signal action (eg, blocked or ignored).
  530.  * Other ignored signals are discarded immediately.
  531.  */
  532. void
  533. _psignal(struct Task *t, int sig)    /* MAY be called in Supervisor/Interrupt  !*/
  534. {
  535.   register int s;
  536.   register sig_t action;
  537.   /* may be another process, so don't use u. here ! */
  538.   struct user *p = (struct user *)t->tc_TrapData;
  539.   int mask;
  540.  
  541.  
  542.   mask = sigmask(sig);
  543.  
  544.   /*
  545.    * If proc is traced, always give parent a chance.
  546.    */
  547.   if (p->p_flag & STRC)
  548.     action = SIG_DFL;
  549.   else 
  550.     {
  551.  
  552.       /* NOTE AMIGA !
  553.        * I can't allow for trap signals to be either ignored or masked out.
  554.        * This would cause the trap to reoccur immediately again, resulting
  555.        * in a deadly loop. So if such a signal gets here, it is converted
  556.        * in a SIGILL, masked in, not ignored, not caught, that's it.
  557.        */
  558.       if (((mask & p->p_sigignore) || (mask & p->p_sigmask))
  559.       && (sig == SIGILL  || sig == SIGBUS || sig == SIGFPE || 
  560.           sig == SIGTRAP || sig == SIGEMT))
  561.     {
  562.       sig = SIGILL;
  563.       mask = sigmask (sig);
  564.       p->p_sigignore &= ~mask;
  565.       p->p_sigmask   &= ~mask;
  566.       p->p_sigcatch  &= ~mask;
  567.       /* that's it, SIGILL is now reset to SIG_DFL, which will exit() */
  568.     }
  569.  
  570.       /*
  571.        * If the signal is being ignored,
  572.        * then we forget about it immediately.
  573.        * (Note: we don't set SIGCONT in p_sigignore,
  574.        * and if it is set to SIG_IGN,
  575.        * action will be SIG_DFL here.)
  576.        */
  577.      if (p->p_sigignore & mask)
  578.     return;
  579.  
  580.      if (p->p_sigmask & mask)
  581.     action = SIG_HOLD;
  582.      else if (p->p_sigcatch & mask)
  583.     action = SIG_CATCH;
  584.      else
  585.     action = SIG_DFL;
  586.     }
  587.  
  588.   switch (sig) 
  589.     {
  590.     case SIGTERM:
  591.       if ((p->p_flag&STRC) || action != SIG_DFL)
  592.     break;
  593.     /* FALLTHROUGH */
  594.  
  595.     case SIGKILL:
  596.       break;
  597.  
  598.     case SIGCONT:
  599.       p->p_sig &= ~stopsigmask;
  600.       break;
  601.  
  602.     case SIGTSTP:
  603.     case SIGTTIN:
  604.     case SIGTTOU:
  605.     case SIGSTOP:
  606.       p->p_sig &= ~sigmask(SIGCONT);
  607.       break;
  608.     }
  609.   p->p_sig |= mask;
  610.  
  611.   /*
  612.    * Defer further processing for signals which are held,
  613.    * except that stopped processes must be continued by SIGCONT.
  614.    */
  615.   if (action == SIG_HOLD && (sig != SIGCONT || p->p_stat != SSTOP))
  616.     return;
  617.  
  618.   setrun(t);
  619. }
  620. /*
  621.  * If the current process has a signal to process (should be caught
  622.  * or cause termination, should interrupt current syscall),
  623.  * return the signal number.  Stop signals with default action
  624.  * are processed immediately, then cleared; they aren't returned.
  625.  * This is asked at least once each time a process enters the
  626.  * system (though this can usually be done without actually
  627.  * calling issig by checking the pending signal masks.)
  628.  */
  629. int
  630. issig(struct user *p)    /* called in SUPERVISOR */
  631. {
  632.   register int sig, mask;
  633.  
  634.   for (;;)
  635.     {
  636.       mask = p->p_sig &~ p->p_sigmask;
  637.       if (p->p_flag&SVFORK)
  638.     mask &= ~stopsigmask;
  639.  
  640.       if (mask == 0)         /* no signal to send */
  641.     return 0;
  642.  
  643.       sig = ffs((long)mask);
  644.       mask = sigmask(sig);
  645.       /*
  646.        * We should see pending but ignored signals
  647.        * only if STRC was on when they were posted.
  648.        */
  649.       if (mask & p->p_sigignore && (p->p_flag&STRC) == 0) 
  650.         {
  651.           p->p_sig &= ~mask;
  652.       continue;
  653.     }
  654.  
  655. #if notyet
  656.       if (p->p_flag&STRC && (p->p_flag&SVFORK) == 0) 
  657.         {
  658.       /*
  659.        * If traced, always stop, and stay
  660.        * stopped until released by the parent.
  661.        */
  662.       p->p_xstat = sig;
  663.       _psignal(p->p_pptr, SIGCHLD);
  664.       do 
  665.             {
  666.           stop(p);
  667.           swtch();
  668.         } 
  669.           while (!procxmt(p) && p->p_flag&STRC);
  670.  
  671.       /*
  672.        * If the traced bit got turned off,
  673.        * go back up to the top to rescan signals.
  674.        * This ensures that p_sig* and u_signal are consistent.
  675.        */
  676.       if ((p->p_flag&STRC) == 0)
  677.         continue;
  678.  
  679.       /*
  680.        * If parent wants us to take the signal,
  681.        * then it will leave it in p->p_xstat;
  682.        * otherwise we just look for signals again.
  683.        */
  684.       p->p_sig &= ~mask;    /* clear the old signal */
  685.       sig = p->p_xstat;
  686.       if (sig == 0)
  687.         continue;
  688.  
  689.       /*
  690.        * Put the new signal into p_sig.
  691.        * If signal is being masked,
  692.        * look for other signals.
  693.        */
  694.       mask = sigmask(sig);
  695.       p->p_sig |= mask;
  696.       if (p->p_sigmask & mask)
  697.         continue;
  698.     }
  699. #endif
  700.  
  701.       /*
  702.        * Decide whether the signal should be returned.
  703.        * Return the signal's number, or fall through
  704.        * to clear it from the pending mask.
  705.        */
  706.       switch ((int)p->u_signal[sig]) 
  707.         {
  708.     case SIG_DFL:
  709. #if notyet
  710.       /*
  711.        * Don't take default actions on system processes.
  712.        */
  713.       if (p->p_ppid == 0)
  714.         break;        /* == ignore */
  715. #endif
  716.       /*
  717.        * If there is a pending stop signal to process
  718.        * with default action, stop here,
  719.        * then clear the signal.  However,
  720.        * if process is member of an orphaned
  721.        * process group, ignore tty stop signals.
  722.        */
  723.       if (mask & stopsigmask) 
  724.         {
  725. #if notyet
  726.           if (p->p_flag&STRC ||
  727.           (p->p_pgru.pg_jobc == 0 && mask & ttystopsigmask))
  728.         break;    /* == ignore */
  729.           u.p_xstat = sig;
  730.           stop(p);
  731.           if ((u.p_pptr->p_flag & SNOCLDSTOP) == 0)
  732.         _psignal(u.p_pptr, SIGCHLD);
  733.           swtch();
  734. #endif
  735.           break;
  736.         } 
  737.           else if (mask & defaultignmask)
  738.         {
  739.           /*
  740.            * Except for SIGCONT, shouldn't get here.
  741.            * Default action is to ignore; drop it.
  742.            */
  743.           break;        /* == ignore */
  744.         }
  745.       else
  746.         return (sig);
  747.       /*NOTREACHED*/
  748.  
  749.     case SIG_IGN:
  750.       /*
  751.        * Masking above should prevent us ever trying
  752.        * to take action on an ignored signal other
  753.        * than SIGCONT, unless process is traced.
  754.        */
  755. #if 0
  756.       if (sig != SIGCONT && (u.p_flag&STRC) == 0)
  757.         printf("issig\n");
  758. #endif
  759.       break;        /* == ignore */
  760.  
  761.     default:
  762.       /*
  763.        * This signal has an action, let
  764.        * psig process it.
  765.        */
  766.       return (sig);
  767.     }
  768.       u.p_sig &= ~mask;        /* take the signal! */
  769.     }
  770.   /* NOTREACHED */
  771. }
  772. #if notyet
  773. /*
  774.  * Put the argument process into the stopped
  775.  * state and notify the parent via wakeup.
  776.  * Signals are handled elsewhere.
  777.  * The process must not be on the run queue.
  778.  */
  779. void
  780. stop(struct Task *t)
  781. {
  782.   struct user *p = (struct user *) t->tc_TrapData;
  783.  
  784.   p->p_stat = SSTOP;
  785.   p->p_flag &= ~SWTED;
  786.   wakeup((caddr_t)u.p_pptr);
  787. }
  788. #endif
  789.  
  790. /*
  791.  * Perform the action specified by the current signal.
  792.  * The usual sequence is:
  793.  *    if (sig = CURSIG(p))
  794.  *        psig(p, sig);
  795.  */
  796. void
  797. psig(struct user *p, int sig)    /* called in SUPERVISOR */
  798. {
  799.   int mask, returnmask;
  800.   register sig_t action; 
  801.  
  802.   do 
  803.     {
  804.       mask = sigmask(sig);
  805.       p->p_sig &= ~mask;
  806.       action = p->u_signal[sig];
  807.       if (action != SIG_DFL) 
  808.         {
  809.        /*
  810.         * Set the new mask value and also defer further
  811.         * occurences of this signal.
  812.         *
  813.         * Special case: user has done a sigpause.  Here the
  814.         * current mask is not of interest, but rather the
  815.          * mask from before the sigpause is what we want
  816.         * restored after the signal processing is completed.
  817.         */
  818. #if usermode
  819.       /* not needed here, no interrupt will play with the signalmask... */
  820.       (void) Disable();
  821. #endif
  822.       if (p->p_flag & SOMASK)
  823.         {
  824.           returnmask = p->u_oldmask;
  825.           p->p_flag &= ~SOMASK;
  826.         }
  827.       else
  828.         returnmask = p->p_sigmask;
  829.       p->p_sigmask |= p->u_sigmask[sig] | mask;
  830. #if usermode
  831.       (void) Enable();
  832. #endif
  833.  
  834.       p->u_ru.ru_nsignals++;
  835.       sendsig(p, action, sig, returnmask, 0, 0);
  836.       continue;
  837.     }
  838.  
  839. #if whatdoesthisdo
  840.       p->u_acflag |= AXSIG;
  841. #endif
  842.  
  843.       switch (sig) 
  844.         {
  845.     case SIGILL:
  846.     case SIGIOT:
  847.     case SIGBUS:
  848.     case SIGQUIT:
  849.     case SIGTRAP:
  850.     case SIGEMT:
  851.     case SIGFPE:
  852.     case SIGSEGV:
  853.     case SIGSYS:
  854.       p->u_sig = sig;
  855.       if (core() == 0)
  856.         sig |= WCOREFLAG;
  857.     }
  858.       /* we can't call exit() when in supervisor mode, have to do this just like
  859.        * it was a signal passed on its own frame */
  860.       sendsig(p, sig_exit, sig, 0, 0, 0);
  861.       /* NOTREACHED */
  862.     
  863.   } while (sig = CURSIG(p));
  864. }
  865.  
  866. /*
  867.  * Create a core image on the file "core".
  868.  * It writes UPAGES block of the
  869.  * user.h area followed by the entire
  870.  * data+stack segments.
  871.  */
  872. int
  873. core()
  874. {
  875.   return -1;
  876. }
  877.  
  878. static void sigprocessgrp(struct Process *proc, int pgrp, int signal)
  879. {
  880.   struct Process *p;
  881.  
  882.   for (p = getuser(proc)->p_cptr; p; p = getuser(p)->p_osptr)
  883.     sigprocessgrp(p, pgrp, signal);
  884.   if (getuser(proc)->p_pgrp == pgrp)
  885.     _psignal((struct Task *)proc, signal);
  886. }
  887.  
  888. void _psignalgrp(struct Process *proc, int signal)
  889. {
  890.   struct Process *p = getuser(proc)->p_pptr;
  891.   struct Process *ok = proc;
  892.  
  893.   /* traverse to the top of the process-tree */
  894.   while (p && p != (struct Process *)1)
  895.     {
  896.       ok = p;
  897.       p = getuser(p)->p_pptr;
  898.     }
  899.   sigprocessgrp(ok, getuser(proc)->p_pgrp, signal);
  900. }
  901.